<template>
  <e-group class="custom-group-wrapper"
    v-bind="$props"
    :button-disabled="disabled"
    :value="editorValue"
    @add="handleCustomCheckAdd"
    @remove="handleCustomCheckRemove">
    <template slot-scope="scope">
      <div class="xcheckbox-item"
        :class="{
          mr40: !(scope.index % 2)
        }">
        <div class="err-tips-wrapper" v-show="scope.item.isShowErrTips">
          <span class="err-tips_title">{{repeatTipText}}</span>
          <i class="err-tips_arrow"></i>
        </div>
        <el-checkbox
          :label="scope.item"
          v-model="scope.item.checked"
          :disabled="!editState"
          @change="handleCustomCheckChange(scope.index, $event)">
          <slot>
            <template v-if="formType === FORM_TYPE_ENUMS.INPUT">
              <el-input class="input-small xsmall"
                v-bind="$props"
                :disabled="!editState"
                :value="scope.item.name"
                @change="handleInputChange(scope.index, {
                  type: FORM_TYPE_ENUMS.INPUT
                }, $event)"
                @blur="handleInputBlur()"/>
            </template>
            <!-- 多值文本框 暂时只用于培训次课 -->
            <template v-if="formType === FORM_TYPE_ENUMS.INPUTS">
              <el-input-number class="inputs-small xsmall" placeholder="次数"
                :bit="1"
                :disabled="!editState"
                v-model="scope.item.tempVl[0]"
                @blur="handleInputBlur()"
                @change="handleInputChange(scope.index, {
                  type: FORM_TYPE_ENUMS.INPUTS,
                  pIndex: 0
                }, $event)"/>
                次，有效期
              <el-input-number class="inputs-small xsmall" placeholder="月数"
                :bit="1"
                :max="12"
                :disabled="!editState"
                v-model="scope.item.tempVl[1]"
                @blur="handleInputBlur()"
                @change="handleInputChange(scope.index, {
                  type: FORM_TYPE_ENUMS.INPUTS,
                  pIndex: 1
                }, $event)"/>
              个月
            </template>
            <template v-if="formType === FORM_TYPE_ENUMS.TIME && pickerOptions">
              <el-date-picker class="date-small xsmall" placeholder="自定义属性"
                v-model="scope.item.name"
                type="datetime"
                format="yyyy-MM-dd HH:mm"
                :disabled="!editState"
                :popper-class="`check-date${scope.item.key}`"
                :picker-options="pickerOptions"
                @change="handleInputChange(scope.index, {
                  type: FORM_TYPE_ENUMS.TIME
                }, $event)"/>
            </template>
          </slot>
        </el-checkbox>
      </div>
    </template>
  </e-group>
</template>
<script>
  import EGroup from '@e-ui/Group'
  import { Input } from '@element-ui'
  import { cloneObj } from 'utils'

  import {
    FORM_TYPE_ENUMS,
    SALE_CUSTOM_CHECK
  } from '../constant'
  export default {
    components: {
      EGroup
    },
    props: {
      ...EGroup.props,
      ...Input.props,
      value: Array,
      // 重名提示文字
      repeatTipText: {
        type: String,
        default: '组别名称不能重复'
      },
      placeholder: {
        type: String,
        default: '自定义属性'
      },
      // 表单类型 默认文本 其他为 日期 次课多文本
      formType: {
        type: Number,
        default: FORM_TYPE_ENUMS.INPUT
      },
      isEdit: {
        type: Boolean,
        default: false
      },
      // 是否可编辑
      editState: {
        type: Boolean,
        default: true
      },
      // 非自定义数据 用来去重名 最基本的格式为字符串数组 或者 含name字段的对象
      fixedData: {
        type: Array,
        default () {
          return []
        }
      }
    },
    data () {
      // 防止新增时，第一项添加改变了value的值
      let newAddItem = []
      if (!this.isEdit || !this.value.length) {
        newAddItem = cloneObj(SALE_CUSTOM_CHECK)
        newAddItem.key = this.unique()
      }
      let editorValue = this.value.concat(newAddItem)
      editorValue = editorValue.map(item => {
        item.checkedState = true // 默认编辑的选择状态都为true
        item.isShowErrTips = false // 默认编辑的提示状态都为false
        return item
      })
      return {
        editorValue,
        FORM_TYPE_ENUMS: FORM_TYPE_ENUMS // 表单类型
      }
    },
    created () {
      // 日期处理
      if (this.formType === FORM_TYPE_ENUMS.TIME) {
        this.pickerOptions = {
          disabledDate (time) {
            return time.getTime() < Date.now() - 8.64e7
          }
        }
        this.editorDate = '' // 日期组件没有v-model选择不了时间
      }
    },
    mounted () {
      // 编辑重名数据处理
      this.$exitNameList = this.fixedData.concat(this.value || []).map(k => typeof k === 'string' ? k : k.name) // 重名数组初始化
    },
    methods: {
      handleCustomCheckAdd () {
        let newAddItem = cloneObj(SALE_CUSTOM_CHECK)
        newAddItem.key = this.unique()
        this.editorValue.push(newAddItem)
      },
      handleCustomCheckRemove (index) {
        let curDelData = this.editorValue[index]
        let curIndex = index + this.fixedData.length // 需要计算已存在的数据
        this.editorValue.splice(index, 1) // 自定义组别删除
        this.$exitNameList.splice(curIndex, 1)
        if (curDelData.checked) { // 如果是选中的 就更新
          this._resetTipState(curDelData)
          this.changeCheckedData()
        }
      },
      handleInputChange (index, { type, pIndex }, newVal = '') {
        // change事件 处理是否选中 取消选中
        newVal = String(newVal).trim() // 文本框可能会有空格
        let oldVal = this.editorValue[index]

        // 处理数据
        if (type === FORM_TYPE_ENUMS.INPUTS) {
          oldVal.tempVl[pIndex] = ~~newVal
          let newArr = oldVal.tempVl.filter(k => k > 0)
          if (newArr.length) {
            if (oldVal.tempVl[0] === 0) {
              newVal = `${oldVal.tempVl[1]}个月（不限次数）`
            } else if (oldVal.tempVl[1] === 0) {
              newVal = `${oldVal.tempVl[0]}次（不限期）`
            } else {
              newVal = `${oldVal.tempVl[0]}次（${oldVal.tempVl[1]}个月）`
            }
            // 格式更改需要在加载值的时候改变 #516
            oldVal.value = 'C_' + oldVal.tempVl.slice(0, 2).join('_') // 限制前2个位置
          } else {
            newVal = ''
            oldVal.value = ''
          }
        }

        let curIndex = index + this.fixedData.length // 需要计算已存在的数据
        if (newVal) {
          // 重名判断
          let exitIndex = this.$exitNameList.findIndex(k => k === newVal)
          let isNameRepeat = exitIndex !== -1 && exitIndex !== curIndex
          oldVal.checked = !isNameRepeat // 重名 则 不能选中，不重名 则 选中
          oldVal.checkedState = !isNameRepeat // 重名 则 不能选中，不重名 则 可以选中
          oldVal.isShowErrTips = isNameRepeat // 重名 则 显示提示， 不重名 则 不显示
        } else {
          oldVal.checked = false
        }
        // 先验证重名 在修改 此处修改会改动editorValue里面的值
        // 只是没有set前，不会触发渲染更新
        oldVal.name = newVal
        this.$exitNameList[curIndex] = newVal
        this.$set(this.editorValue, index, oldVal)
        // 日期 改变之后 才触发表格更新
        if (type === FORM_TYPE_ENUMS.TIME || type === FORM_TYPE_ENUMS.INPUTS) {
          this.changeCheckedData()
        }
      },
      handleInputBlur () {
        // 中转事件
        // 文本框 失去焦点时 才触发表格数据更新
        this.changeCheckedData()
      },
      handleCustomCheckChange (index) {
        // 中转事件
        // 自定义属性选中事件`
        let curData = this.editorValue[index]
        if (curData.checkedState) { // 可选中
          if (curData.name) {
            this.changeCheckedData()
          }
        } else { // 不可选中
          curData.checked = !1 // 取消选中
          this.$set(this.editorValue, index, curData)
        }
      },
      _resetTipState (curDelData) {
        // 重置重名提示
        let delArr = this.editorValue.filter(k => k.name === curDelData.name)
        if (!curDelData.isShowErrTips && delArr.length) {
          let changeIndex = this.editorValue.findIndex(k => k.key === delArr[0].key)
          let changeItem = this.editorValue[changeIndex]
          changeItem.checked = true // 选中
          changeItem.isShowErrTips = false // 隐藏重名提示
          this.$set(this.editorValue, changeIndex, changeItem)
        }
      },
      changeCheckedData () {
        let result = this.editorValue.filter(k => k.checked && k.name.trim())
        this.$emit('input', result).$emit('change', result)
      }
    }
  }
</script>
<style lang="scss" scoped>
  .custom-group-wrapper{
    .xcheckbox-item{
      position: relative;
      display: inline;
      .xsmall {
        width: 260px;
        &.input-small{
          margin-left: 4px;
        }
        &.inputs-small{
          width: 75px;
        }
      }
    }
    .err-tips-wrapper{
      position: absolute;
      left: -96px;
      top: -7px;
      z-index: 2001;
      margin-right: 12px;
      padding: 10px;
      border-radius: 4px;
      border: 1px solid #999;
      transform-origin: right center 0px;
      background: #fff;
      font-size: 12px;
      line-height: 1.2;
      .err-tips_arrow{
        position: absolute;
        display: block;
        top: 50%;
        right: -12px;
        width: 0;
        height: 0;
        border-color: transparent;
        border-style: solid;
        border-left-color: #1f3d33;
        border-right-width: 0;
        border-width: 6px;
        transform: translateY(-50%);
        &:after{
          position: absolute;
          display: block;
          width: 0;
          height: 0;
          border-color: transparent;
          border-style: solid;
          content: " ";
          border-width: 5px;
          right: 1px;
          bottom: -5px;
          margin-left: -5px;
          border-right-width: 0;
          border-left-color: #1f3d33;
          border-left-color: #fff;
        }
      }
    }
  }
</style>
